﻿using Core.Container;
using Core.Interface;
using Core.Log;
using Core.MessageEvent;
using ModBus.Mode;
using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Mvvm;
using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace ModBus.ViewModels
{
    public class ModBusTCPViewModel : BindableBase
    {
        ModBusTCP modBusTCP;    
        Container<ModBusDevice> container;
        DataContainer<IPEndPoint> IPEndPoints;
        Notify notifyCollect;
        public ModBusTCPViewModel(IContainerExtension container, IEventAggregator ea)
        {
            this.container = container.Resolve<Container<ModBusDevice>>("ModBusDevice");
            this.IPEndPoints = container.Resolve<DataContainer<IPEndPoint>>("IPEndPoints");
            ea.GetEvent<MessageEvent>().Subscribe(Receive, ThreadOption.UIThread, false);
            notifyCollect = NotifyCollect.NotifyContainer["Error"];
        }

        private void Receive(string key)
        {
            try
            {
                if (container.Get(key) is ModBusTCP tCP)
                {
                    modBusTCP = tCP;
                    IPEndPoint = modBusTCP.IPEndPoint.ToString();
                }
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }                
        }

        #region 界面IP改变后
        private void IPChange()
        {
            try
            {
                var ipPortString = iPEndPoint.Split(':');
                IPAddress ipAddress = IPAddress.Parse(ipPortString[0]);
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, Convert.ToInt32(ipPortString[1]));
                modBusTCP.IPEndPoint = ipEndPoint;
                IPEndPoints.Add(modBusTCP.Name, ipEndPoint);
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }            
        }
        private string iPEndPoint;
        public string IPEndPoint
        {
            get { return iPEndPoint; }
            set { SetProperty(ref iPEndPoint, value, ()=>IPChange() );}
        }
        #endregion

        //连接
        public ICommand ConnectCommand
        { get => new DelegateCommand(Connect); }
        private void Connect()
        {
            try
            {
                Task.Run(() => modBusTCP.Connect()).ContinueWith(
                     t =>
                     {
                         if (t.Result)
                             MessageBox.Show("连接成功");
                         else
                             MessageBox.Show("连接失败");
                     });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        //断开连接
        public ICommand DisconnectCommand
        { get => new DelegateCommand(Disconnect); }
        private void Disconnect()
        {
            try
            {
                modBusTCP.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        #region
        private ushort uReadStartAdd;
        public ushort UReadStartAdd
        {
            get { return uReadStartAdd; }
            set { SetProperty(ref uReadStartAdd, value);}
        }
        
        private ushort uReadSize;
        public ushort UReadSize
        {
            get { return uReadSize; }
            set { SetProperty(ref uReadSize, value); }
        }

        private string uReadValue;
        public string UReadValue
        {
            get { return uReadValue; }
            set { SetProperty(ref uReadValue, value); }
        }
        public ICommand ReadUshort
        { get => new DelegateCommand(ReadUshortMethod); }
        private void ReadUshortMethod()
        {
            try
            {
                if (UReadSize == 0) UReadSize = 1;
                modBusTCP.ReadRegister(UReadStartAdd, UReadSize, out ushort[] values);
                UReadValue = string.Join("，", values);
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }
        }
     
        private ushort uWriteStartAdd;
        public ushort UWriteStartAdd
        {
            get { return uWriteStartAdd; }
            set { SetProperty(ref uWriteStartAdd,value); }
        }
        private ushort uWriteSize;
        public ushort UWriteSize
        {
            get { return uWriteSize; }
            set { SetProperty(ref uWriteSize, value); }
        }
        private string uWriteValue;
        public string UWriteValue
        {
            get { return uWriteValue; }
            set { SetProperty(ref uWriteValue, value); }
        }
        public ICommand WriteUshort
        { get => new DelegateCommand(WriteUshortMethod); }
        private void WriteUshortMethod()
        {
            try
            {
                if (UWriteValue == null) return;
                string[] values = UWriteValue?.Split(new char[2] { ',', '，' });
                var ushorts = Array.ConvertAll(values, ushort.Parse);
                if (UWriteSize == 0) UWriteSize = 1;
                if (modBusTCP.WriteRegister(UWriteStartAdd, UWriteSize, ushorts))
                { MessageBox.Show("写入成功"); }
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }          
        }


        private ushort fReadStartAdd;
        public ushort FReadStartAdd
        {
            get { return fReadStartAdd; }
            set { SetProperty(ref fReadStartAdd,value); }
        }

        private ushort fReadSize;
        public ushort FReadSize
        {
            get { return fReadSize; }
            set { SetProperty(ref fReadSize, value); }
        }

        private string fReadValue;
        public string FReadValue
        {
            get { return fReadValue; }
            set { SetProperty(ref fReadValue,value); }
        }
        public ICommand ReadFloat
        { get => new DelegateCommand(ReadFloatMethod); }
        private void ReadFloatMethod()
        {
            try
            {
                if (FReadSize == 0) FReadSize = 1;
                modBusTCP.ReadFloat(FReadStartAdd, FReadSize, out float[] values);
                FReadValue = string.Join("，", values);
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }
        }


        private ushort fWriteStartAdd;
        public ushort FWriteStartAdd
        {
            get { return fWriteStartAdd; }
            set { SetProperty(ref fWriteStartAdd, value); }
        }
        private ushort fWriteSize;
        public ushort FWriteSize
        {
            get { return fWriteSize; }
            set { SetProperty(ref fWriteSize, value); }
        }
        private string fWriteValue;
        public string FWriteValue
        {
            get { return fWriteValue; }
            set { SetProperty(ref fWriteValue, value); }
        }
        public ICommand WriteFloat
        { get => new DelegateCommand(WriteFloatMethod); }
        private void WriteFloatMethod()
        {
            try
            {
                string[] values = FWriteValue.Split(new char[2] { ',', '，' });
                var floats = Array.ConvertAll(values, float.Parse);
                if (FWriteSize == 0) FWriteSize = 1;
                if (modBusTCP.WriteFloat(FWriteStartAdd, FWriteSize, floats))
                { MessageBox.Show("写入成功"); }
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }        
        }
        #endregion
    }
}
